/*
 * @Author: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @Date: 2025-09-05 09:33:14
 * @LastEditors: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @LastEditTime: 2025-09-19 14:22:39
 * @FilePath: /server/workspace/src/base/fdmanager.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "fdmanager.h"
#include "base/hook.h"
#include "base/mutex.h"
#include "sys/fcntl.h"
#include "sys/stat.h"
#include <asm-generic/socket.h>
#include <cstdint>
#include <fcntl.h>
#include "Singleton.h"
namespace Yizhi {
   FdCtx::FdCtx(int fd)
   :m_fd(fd)
   ,m_isInited(false)
   ,m_isClosed(false)
   ,m_isSocket(false)
   ,m_sysNonblock(false)
   ,m_userNonblock(false)
   ,m_recvTimeout(-1)
   ,m_sendTimeout(-1){
        init();
   }



   bool FdCtx::init(){
    if(m_isInited){
        return true;
    }

    m_recvTimeout=-1;
    m_sendTimeout=-1;

    struct stat fdstat;

    if(-1==fstat(m_fd,&fdstat)){
        m_isInited=false;
        m_isSocket=false;
    }
    else {
        m_isInited=true;
        m_isSocket=S_ISSOCK(fdstat.st_mode);
    }
    //当fd为socket
    if(m_isSocket){
        auto flags=fcntl_f(m_fd,F_GETFL,0);
        if(!(flags&O_NONBLOCK)){
            fcntl_f(m_fd,F_SETFL,flags|O_NONBLOCK);
           
        }
        m_sysNonblock=true;
        
    }
    else{
        m_sysNonblock=false;
    }
    


    m_userNonblock=false;
    m_isClosed=false;
    return m_isInited;
   }

   uint64_t FdCtx::getTime(int type){
    if(type==SO_RCVTIMEO){
        return m_recvTimeout;
    }
    return m_sendTimeout;
   }


   void FdCtx::setTime(uint64_t timeout,int type){
     if(type==SO_RCVTIMEO){
        m_recvTimeout=timeout;
     }
     else{
        m_sendTimeout=timeout;
     }
   }

   FdCtx::~FdCtx(){

   }

   FdManager::FdManager(){
    m_datas.resize(64);
   }



   FdCtx::ptr FdManager::get(int fd,bool auto_create){
    RWMutexType::ReadLock rlock(m_mutex);    
    if(m_datas.size()<=fd){
        if(auto_create==false){
            return  nullptr;
        }
    }
    else{
        if(m_datas[fd]||!auto_create){
            return m_datas[fd];
        }
    }

    rlock.unlock();
    RWMutexType::WriteLock wlock(m_mutex);
    if(fd>=m_datas.size()){
        m_datas.resize(fd*1.5);
    }
    m_datas[fd].reset(new FdCtx(fd));
    return  m_datas[fd];
   }

   void FdManager::del(int fd){
    RWMutexType::ReadLock rlock(m_mutex);
    if(fd>=m_datas.size()){
        return;
    }
    m_datas[fd].reset();
   }




}